package com.hd.trans.framework.dialog

import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.os.Build
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.RelativeLayout
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseQuickAdapter.AnimationType
import com.chad.library.adapter.base.entity.node.BaseNode
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.google.android.material.tabs.TabLayout
import com.hd.trans.R
import com.hd.trans.binding.visible
import com.hd.trans.databinding.DialogLanguageBinding
import com.hd.trans.db.DataBaseMgr
import com.hd.trans.db.bean.ChildBottomNode
import com.hd.trans.db.bean.ChildTopNode
import com.hd.trans.db.bean.HuDunLanguage
import com.hd.trans.db.bean.LanguageGroup
import com.hd.trans.utils.DensityUtils
import com.hd.trans.utils.DisplayUtils
import com.hd.trans.utils.ScreenUtil

class LanguageDialog() : BaseDialogFragment<DialogLanguageBinding>(R.layout.dialog_language),
    OnItemClickListener, View.OnTouchListener {

    //构造函数
    constructor(
        from: HuDunLanguage,
        to: HuDunLanguage? = null,
        isFrom: Boolean = true,
        fromType: LanguageDialogType = LanguageDialogType.TEXT,
        toType: LanguageDialogType? = null,
    ) : this() {
        this.fromLang = from
        this.toLang = to?:from
        this.isFrom = isFrom
        this.fromType = fromType
        this.toType = toType
    }

    //构造函数2
    constructor(
        from: HuDunLanguage,
        to: HuDunLanguage? = null,
        isFrom: Boolean = true,
        fromType: LanguageDialogType = LanguageDialogType.TEXT,
        toType: LanguageDialogType? = null,
        showType: DialogType? = DialogType.ONE,
    ) : this() {
        this.fromLang = from
        this.toLang = to?:from
        this.isFrom = isFrom
        this.fromType = fromType
        this.toType = toType
        this.showType = showType
    }


    private var listener: OnLanguageChangedListener? = null
    private lateinit var adapter: LanguageDialogAdapter
    private var letters: ArrayList<String> = arrayListOf()
    private var newList: ArrayList<BaseNode> = arrayListOf()
    private lateinit var fromLang: HuDunLanguage
    private lateinit var toLang: HuDunLanguage
    private var isFrom: Boolean = true
    private var fromType: LanguageDialogType = LanguageDialogType.TEXT
    private var toType: LanguageDialogType? = null
    var showType: DialogType? = DialogType.ONE
    var isOfflineLang: Boolean = false
    private lateinit var currentType: LanguageDialogType
    var cancel: (() -> Unit)? = null
    var confirm: ((from: HuDunLanguage, to: HuDunLanguage) -> Unit)? = null
    override val gravity: Int
        get() = Gravity.BOTTOM
    override val dialogAnim: Int
        get() = R.style.BottomAnimStyle
    override val windowHeight: Int
        get() = ScreenUtil.getScreenHeight(activity) * 4 / 5

    @SuppressLint("ClickableViewAccessibility")
    override fun initView() {
        ScreenUtil.init(activity)
        currentType = if (isFrom) {fromType} else {toType?:fromType}
        dataBinding.apply {
            if(toType == null){
                topTab1.visible = false
                topTab2.visible = false
            }else{
                topTab1.visible = showType == DialogType.ONE
                topTab2.visible = showType == DialogType.TWO
            }
            updateText()
            val manager = LinearLayoutManager(context)
            recyclerView.layoutManager = manager
            recyclerView.itemAnimator = DefaultItemAnimator()
            //设置item间距
            recyclerView.addItemDecoration(
                LanguageItemDecoration(
                    DensityUtils.dip2px(
                        context,
                        if(showType == DialogType.ONE) 3f else 0f
                    )
                )
            )
            adapter = LanguageDialogAdapter(showType)
            adapter.checkedItem = if (isFrom) {fromLang} else {toLang}
            //设置条目加载动画。
            if(showType == DialogType.ONE){
                adapter.setAnimationWithDefault(AnimationType.SlideInBottom)

                tabLayout.addTab(tabLayout.newTab().setText(fromLang.name), 0)
                tabLayout.addTab(tabLayout.newTab().setText(toLang.name), 1)

                val position = if (isFrom) {0} else {1}
                tabLayout.getTabAt(position)?.select()
            }else if(showType == DialogType.TWO){
                txtFrom.text = fromLang.name
                txtTo.text = toLang.name
                setTranTypeStatus(isFrom)
                txtFrom.setOnClickListener{
                    setTranTypeStatus(true)
                }
                txtTo.setOnClickListener {
                    setTranTypeStatus(false)
                }
            }
            adapter.animationEnable = showType == DialogType.ONE

            recyclerView.adapter = adapter
            adapter.setOnItemClickListener(this@LanguageDialog)

            rlRoot.setOnTouchListener(this@LanguageDialog)
            recyclerView.setOnTouchListener(this@LanguageDialog)
            ivDownTips.setOnTouchListener(this@LanguageDialog)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                recyclerView.setOnScrollChangeListener { v: View?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
                    val lastTopPosition = manager.findFirstCompletelyVisibleItemPosition()
                    isTop = lastTopPosition == 0
                }
            }

            sidleLetter.setOnTouchingChangedListener { str ->
                var index = 0
                for (i in adapter.data.indices) {
                    val item = adapter.data[i]
                    if (item is LanguageGroup) {
                        if (str == (item as LanguageGroup).name) {
                            index = i
                            break
                        }
                    } else {
                        continue
                    }
                }
                //                Logger.i("===========index : "+index);
                (recyclerView.layoutManager as LinearLayoutManager?)!!.scrollToPositionWithOffset(
                    index,
                    0)
                (recyclerView.layoutManager as LinearLayoutManager?)!!.stackFromEnd =
                    true
                //                recyclerView.scrollToPosition( index );
                tvLetter.text = str
                tvLetter.visibility = View.VISIBLE

                mHandler.removeCallbacks(overlayThread)
                mHandler.postDelayed(overlayThread, 500)
            }

            ivDownTips.setOnClickListener { dismiss() }

            tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                override fun onTabSelected(tab: TabLayout.Tab) {
                    isFrom = tab.position == 0
                    adapter.checkedItem = if (isFrom) {fromLang} else {toLang}
                    currentType = if (isFrom) {fromType} else {toType?:fromType}
                    updateText()
                    initLanguages()
                }

                override fun onTabUnselected(tab: TabLayout.Tab) {}
                override fun onTabReselected(tab: TabLayout.Tab) {}
            })
        }
        initLanguages()
    }

    private fun setTranTypeStatus(isFromPage: Boolean) {
        dataBinding.txtFrom.isSelected = isFromPage
        dataBinding.txtTo.isSelected = !isFromPage

        isFrom = isFromPage
        adapter.checkedItem = if (isFrom) {fromLang} else {toLang}
        currentType = if (isFrom) {fromType} else {toType?:fromType}
        updateText()
        initLanguages()
    }

    private fun updateText() {
        when(currentType){
            LanguageDialogType.TEXT -> {
                dataBinding.tvTitle.text = getString(R.string.trans_from_language)
            }
            LanguageDialogType.VOICE,
            LanguageDialogType.FILE,
            LanguageDialogType.WORD,
            -> {
                dataBinding.tvTitle.text = getString(R.string.trans_voice_from_language)
            }
            LanguageDialogType.TO_TEXT,
            LanguageDialogType.TO_VOICE,
            LanguageDialogType.TO_FILE,
            LanguageDialogType.TO_WORD,
            LanguageDialogType.TO_FILE_FILTRATION,
            -> {
                dataBinding.tvTitle.text = getString(R.string.trans_to_language)
            }
        }
    }

    private fun setLetters(groupList: List<LanguageGroup>){
        //字母列表添加。
        letters.clear()
        for (group in groupList) {
            if (group.name.matches(Regex("[A-Z]"))) {
                if (!letters.contains(group.name)) {
                    letters.add(group.name)
                }
            }
        }
        letters.add(0, "#")
        dataBinding.sidleLetter.setLetterList(letters)

    }

    private fun initLanguages() {
        //数据库获取语言列表
        val groupList = DataBaseMgr.getInstance().getLanguageGroups(currentType, isFrom, isOfflineLang)
        //语音翻译，添加常用语言组。
        val list = ArrayList<BaseNode>(DataBaseMgr.getInstance().getCommonRecordLanguages(currentType, isFrom, isOfflineLang))
        //设置字母列表
        setLetters(groupList)
        if (list != null && list.size > 0) {
            //创建常用语言组。
            val groupHot = LanguageGroup("常用语言")
            groupHot.setItems(list)
            //把常用语言组添加到数据列表里。
            groupList.add(0, groupHot)
        }

        if(showType == DialogType.TWO){
            groupList.forEach {
                it.childNode?.add(0, ChildTopNode())
                it.childNode?.add(ChildBottomNode())
            }
        }

        //添加脚布局
        /*FootNode footNode = new FootNode("foot");
        ArrayList<BaseNode> footNodes = new ArrayList<>();
        footNodes.add(footNode);
        LanguageGroup groupFoot = new LanguageGroup("");
        groupFoot.setItems(footNodes);
        groupList.add(groupFoot);*/

        //创建新的数据列表
        newList.clear()
        newList.addAll(groupList)
        //把新的数据给adapter。
        adapter.setNewData(newList)
    }

    override fun onItemClick(baseAadapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
        val item = adapter.getItem(position)
        if (item is HuDunLanguage) {
            if (item != adapter.checkedItem) {
                if(isFrom) {
                    if(item == toLang) {
                        toLang = if("auto" == fromLang.translateCode){
                            if("zh" == item.translateCode){
                                DataBaseMgr.getInstance().getLanguageByTransCode("en")
                            }else{
                                DataBaseMgr.getInstance().getLanguageByTransCode("zh")
                            }
                        }else{
                            fromLang
                        }
                    }
                    fromLang = item
                } else {
                    if(item == fromLang) {
                        fromLang = toLang
                    }
                    toLang = item
                }
                listener?.onLanguageChanged(fromLang, toLang , item)

                if ("auto" != item.translateCode) {
                    if(currentType != LanguageDialogType.WORD
                        && currentType != LanguageDialogType.TO_WORD){
                        DataBaseMgr.getInstance().addLanguageRecord(item, false)
                    }
                }
            }
            dismiss()
        }
    }


    private var isTop = false
    private var downY = 0f
    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        var result = false
        if (event!!.action == MotionEvent.ACTION_DOWN) {
            downY = event.y
        } else if (event.action == MotionEvent.ACTION_MOVE) {
            val moveY = event.y
            if (v is RecyclerView) {
                if (!isTop || downY == 0f) {
                    downY = moveY
                }
            }
            val mDy: Float = moveY - downY
            val value = dataBinding.root.translationY + mDy
            if (dataBinding.root.translationY >= 0 && value >= 0 && (isTop || v !is RecyclerView)) {
                dataBinding.root.translationY = value
                val mScale = dataBinding.root.translationY / ScreenUtil.getScreenHeight()
                if (mScale <= 1.0f) {
                    dataBinding.root.alpha = 1.0f - mScale
                }
                result = true
            } else {
                result = false
            }
        } else if (event.action == MotionEvent.ACTION_UP) {
            if (dataBinding.root.translationY >= ScreenUtil.getScreenHeight() / 3) {
                hideLanguageDialog()
            } else if (dataBinding.root.translationY > 0f) {
                showLanguageDialog()
            }
            downY = 0f
        }
        return result
    }

    private fun hideLanguageDialog() {
        ObjectAnimator.ofFloat(dataBinding.root, View.TRANSLATION_Y.name, ScreenUtil.getScreenHeight().toFloat())
            .setDuration(300).start()
        ObjectAnimator.ofFloat(dataBinding.root, View.ALPHA.name, 0f).setDuration(300).start()
        dismiss()
    }

    private fun showLanguageDialog() {
        ObjectAnimator.ofFloat(dataBinding.root, View.TRANSLATION_Y.name, 0f).setDuration(300).start()
        ObjectAnimator.ofFloat(dataBinding.root, View.ALPHA.name, 1f).setDuration(300).start()
    }

    /* 触摸右侧拼音 */
    private val overlayThread = Runnable { dataBinding.tvLetter.visibility = View.GONE }

    interface OnLanguageChangedListener {
        fun onLanguageChanged(fromLanguage: HuDunLanguage, toLanguage: HuDunLanguage, selectedLanguage: HuDunLanguage)
    }

    fun setOnLanguageChangedListener(onLanguageChangedListener: OnLanguageChangedListener): LanguageDialog {
        this.listener = onLanguageChangedListener
        return this
    }

}

enum class LanguageDialogType {
    TEXT, VOICE, FILE, WORD, TO_TEXT, TO_VOICE , TO_FILE, TO_WORD, TO_FILE_FILTRATION
}

enum class DialogType {
    ONE, TWO
}